﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Text;
using PicoInterface;

namespace PicoInvokeWebSvc
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class PicoIOSvc : System.Web.Services.WebService
    {

        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }

        public const int BASE_ADDR = 184549376;
        public const int IO_ADDR = 184614912;
        public const int IO_STATUS_REG_ADDR = BASE_ADDR + 6;

        [WebMethod]
        public string Attach(string sImageName)
        {
            string sResult = "";

            StringBuilder buffer = new StringBuilder(1024, 1024);
            if (!PicoInvoke.CreatePicoXface("c:\\pico\\bin\\"))
            {
                return PicoInvoke.GetLastError();
            }

            PicoInvoke.GetCurrentImage(buffer);
            if (buffer.ToString().Length == 0)
                return "Error reading getting pico image file name \n" + PicoInvoke.GetLastError();
            sResult += buffer.ToString() + "\n";

            PicoInvoke.Reboot(sImageName, true);

            if (!PicoInvoke.GetCurrentImage(buffer))
                if (buffer.ToString().Length == 0)
                    return "Error reading getting pico image file name \n" + PicoInvoke.GetLastError();

            sResult += buffer.ToString() + "\n";
            return sResult;
        }

        [WebMethod]
        public void Reset()
        {
            PicoInvoke.WriteDevice(BASE_ADDR, 3);
        }

        [WebMethod]
        public void StopClock()
        {
            PicoInvoke.WriteDevice(BASE_ADDR, 0);
        }

        [WebMethod]
        public void StartClock()
        {
            //string cyclesBinary = RapidHDL.Conversion.IntToBinaryString(16383, 14) + "01";
            string cyclesBinary = RapidHDL.Conversion.IntToBinaryString(1024, 14) + "01";
            PicoInvoke.WriteDevice(BASE_ADDR, RapidHDL.Conversion.StringBinaryToInt(cyclesBinary));
        }

        [WebMethod]
        public void StartClockCycles(int cycles)
        {
            int loops = 1;

            if (cycles > 16000)
            {
                loops = cycles / 16000;
                cycles = 1600;
            }

            double secs = cycles / 25.0 / 1000000.0;
            int delay = (int)(secs * 1000);
            delay += 1;

            //JNA modify here if base clock speed changes!
            string cyclesBinary = RapidHDL.Conversion.IntToBinaryString(cycles * 2, 14) + "01";

            for (int loopIdx = 0; loopIdx < loops; loopIdx++)
            {
                PicoInvoke.WriteDevice(BASE_ADDR, RapidHDL.Conversion.StringBinaryToInt(cyclesBinary));
                //System.Threading.Thread.Sleep(delay);
            }
        }

        [WebMethod]
        public void WriteData(int value)
        {
            string valueBinary = RapidHDL.Conversion.IntToBinaryString(value, 13) + "100";
            PicoInvoke.WriteDevice(BASE_ADDR, RapidHDL.Conversion.StringBinaryToInt(valueBinary));
        }

        [WebMethod]
        public void StoreAddress(int addr)
        {
            // this loads the address to be used by WriteData
            string valueBinary = RapidHDL.Conversion.IntToBinaryString(addr, 13) + "000";
            PicoInvoke.WriteDevice(BASE_ADDR, RapidHDL.Conversion.StringBinaryToInt(valueBinary));
        }


        [WebMethod]
        public int Read(int addr)
        {
            string addrBinary = RapidHDL.Conversion.IntToBinaryString(addr, 14) + "10";
            PicoInvoke.WriteDevice(BASE_ADDR, RapidHDL.Conversion.StringBinaryToInt(addrBinary));
            return PicoInvoke.ReadDevice(BASE_ADDR);
        }

        [WebMethod]
        public int ReadIOStatusReg()
        {
            return PicoInvoke.ReadDevice(IO_STATUS_REG_ADDR);
        }

        [WebMethod]
        public void WriteArray(ushort[] data, int length)
        {
            PicoInvoke.WriteDeviceArray(IO_ADDR, data, length);
        }

        [WebMethod]
        public void ReadArray(ushort[] data, int length)
        {
            PicoInvoke.ReadDeviceArray(IO_ADDR, data, length);
        }
    }
}
